#ifndef IINSTANCEDMESH_H
#define IINSTANCEDMESH_H

#include <export.h>
#include <gfx/imesh.h>
#include <gfx/programparametername.h>
#include <vector>

class  ceBoundingBox;
class  ceMesh;
struct ceRenderEnvironment;
struct ceVector2f;
struct ceVector3f;
struct ceVector4f;
struct iDevice;
struct iLevelOfDetailSolver;

/**
 * \addtogroup graphics
 * @{
 */
/// Type of instanced data
enum ceInstanceDataType
{
	IDT_Float,
	IDT_Vector2,
	IDT_Vector3,
	IDT_Vector4
};

/**
 * @brief Struct holding per instance data
 */
struct ceInstancedData
{
	ceProgramParameterName		Binding;
  ceInstanceDataType				Type;
	union 
	{
    void*                   Data;
		float*									Float;
		ceVector2f*							Vec2;
		ceVector3f*							Vec3;
		ceVector4f*							Vec4;
	};
};

/**
 * @brief Interface for dynamicaly creating instances
 */
struct iInstanceGenerator : public iObject
{

	virtual void Generate (const ceRenderEnvironment&			env, 
                         iDevice*											device,
                         std::vector<ceInstancedData>&	data,
												 unsigned&											num, 
												 unsigned&											maxNum) = 0;

};

/**
 * @brief Interface for rendering the same mesh mutliple times.
 */
struct iInstancedMesh : public iMesh
{

  virtual void UpdateBoundingBox () = 0;
	virtual void SetBoundingBox (const ceBoundingBox& bbox) = 0;

  virtual void SetMesh (ceMesh* mesh) = 0;
  virtual const ceMesh* GetMesh () const = 0;
  virtual ceMesh* GetMesh() = 0;

  virtual void SetLevelOfDetailSolver (iLevelOfDetailSolver* solver) = 0;
  virtual iLevelOfDetailSolver* GetLevelOfDetailSolver () = 0;

	virtual void SetInstanceGenerator (iInstanceGenerator* generator) = 0;
	virtual iInstanceGenerator* GetInstanceGenerator () const = 0;

  virtual void AddInstanceData (const ceInstancedData& data) = 0;
  virtual const ceInstancedData& GetInstanceData (unsigned idx) const = 0;
	virtual unsigned GetNumberOfInstanceData () const = 0;

  virtual void SetNumberOfInstances (unsigned instanceCount) = 0;
  virtual unsigned GetNumberOfInstances () const = 0;
};

/** @} */

#endif // IINSTANCEDMESH_H
